package com.hu.biz.util;

import com.hu.common.util.adm.Assert;
import com.hu.common.util.adm.ObjectParser;
import lombok.extern.log4j.Log4j2;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 355760
 * @ClassName http请求客户端
 * @Description 网络请求工具类
 */
@Log4j2
public class HttpClient {
    private static final byte[] LOCKER = new byte[0];
    private static HttpClient mInstance;
    private final OkHttpClient mOkHttpClient;

    private HttpClient() {
        OkHttpClient.Builder ClientBuilder = new OkHttpClient.Builder();
        //读取超时
        ClientBuilder.readTimeout(20, TimeUnit.SECONDS);
        //连接超时
        ClientBuilder.connectTimeout(6, TimeUnit.SECONDS);
        //写入超时
        ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);
        ClientBuilder.hostnameVerifier((hostname, session) -> true);
        mOkHttpClient = ClientBuilder.build();
    }


    public static HttpClient getInstance() {
        if (mInstance == null) {
            synchronized (LOCKER) {
                if (mInstance == null) {
                    mInstance = new HttpClient();
                }
            }
        }
        return mInstance;
    }

    /**
     * get请求，同步方式，获取网络数据，是在主线程中执行的，需要新起线程，将其放到子线程中执行
     */
    public Response getDataSynFromNet(String url) {
        //1 构造Request
        Request.Builder builder = new Request.Builder();
        Request request = builder.get().url(url).build();
        //2 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //3 执行Call，得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * post请求，同步方式，提交数据，是在主线程中执行的，需要新起线程，将其放到子线程中执行
     */
    public Response postDataSynToNet(String url, RequestBody body, Map<String, String> headerMap) throws IOException {
        // 构造Request
        Request.Builder requestBuilder = new Request.Builder().post(body).url(url);
        if (Assert.notEmpty(headerMap)) {
            headerMap.forEach(requestBuilder::addHeader);
        }
        // 将Request封装为Call
        Request request = requestBuilder.build();
        Call call = mOkHttpClient.newCall(request);
        // 执行Call，得到response
        return call.execute();
    }

    /**
     * 自定义网络回调接口
     */
    public interface MyNetCall {
        void success(Call call, Response response) throws IOException;

        void failed(Call call, IOException e);
    }

    /**
     * get请求，异步方式，获取网络数据，是在子线程中执行的，需要切换到主线程才能更新UI
     */
    public void getDataAsynFromNet(String url, final MyNetCall myNetCall) {
        //1 构造Request
        Request.Builder builder = new Request.Builder();
        Request request = builder.get().url(url).build();
        //2 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //3 执行Call
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                myNetCall.failed(call, e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                myNetCall.success(call, response);

            }
        });
    }

    /**
     * post请求，异步方式，提交数据，是在子线程中执行的，需要切换到主线程才能更新UI
     */
    public void postDataAsynToNet(String url, RequestBody body, final MyNetCall myNetCall) {
        //2 构造Request
        Request.Builder requestBuilder = new Request.Builder();
        Request request = requestBuilder.post(body).url(url).build();
        //3 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //4 执行Call
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                myNetCall.failed(call, e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                myNetCall.success(call, response);

            }
        });
    }

    /**
     * post的请求参数，构造RequestBody
     */
    private RequestBody setRequestFormBody(Map<String, String> BodyParams) {
        RequestBody body;
        FormBody.Builder formEncodingBuilder = new FormBody.Builder();
        if (BodyParams != null) {
            Iterator<String> iterator = BodyParams.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                formEncodingBuilder.add(key, BodyParams.get(key));
                log.info("post http: {}", "post_Params===" + key + "====" + BodyParams.get(key));
            }
        }
        body = formEncodingBuilder.build();
        return body;

    }

    public RequestBody setRequestJsonBody(Object argObj) {
        return RequestBody.create(ObjectParser.toJson(argObj).getBytes(StandardCharsets.UTF_8));
    }


}
